#include "PreCompile.h"
#include "Program.h"

// Construct the Program
Program::Program() :
	m_pApp(NULL),
	m_bDisposed(false)
{
	Initialize();
}

// Detructe the Program
Program::~Program()
{
	Destory();
}

// Initialize the Program
void Program::Initialize()
{
	// Create the App
	CreateApp();

	// Create console
	CreateConsole();
}

// Destory the Program
void Program::Destory()
{
	if (!GetDisposed())
	{
		SetDisposed(true);

		// Destory the console
		DestoryConsole();

		// Destory the App
		DestoryApp();
	}
}

// Is debug mode
bool Program::IsDebugMode()
{
	if (GetApp()->IsDebugMode())
	{
		return true;
	}

	return false;
}

// Configure console window
void Program::ConfigConsole()
{
	typedef HWND(WINAPI *PROCGETCONSOLEWINDOW)();

	PROCGETCONSOLEWINDOW GetConsoleWindow;

	HMODULE hKernel32 = GetModuleHandle(_T("kernel32"));

	GetConsoleWindow = (PROCGETCONSOLEWINDOW)GetProcAddress(hKernel32, "GetConsoleWindow");

	HWND hwnd = GetConsoleWindow();

	// Set window title
	::SetConsoleTitle(_T("KernelDebugger"));

	//// Disable the close button
	//HMENU hMenu;

	//hMenu = ::GetSystemMenu(hwnd, false);

	//::EnableMenuItem(hMenu, SC_CLOSE, MF_GRAYED | MF_BYCOMMAND);
}

// Create console
void Program::CreateConsole()
{
	if (GetApp() == NULL)
	{
		return;
	}

	if (IsDebugMode())
	{
		::AllocConsole();

		// Configure console window
		ConfigConsole();

		// Redirect cout to this console
		freopen("CONOUT$", "w+t", stdout);

		// Redirect cin to this console
		freopen("CONIN$", "r+t", stdin);
	}
}

// Destory the console
void Program::DestoryConsole()
{
	if (IsDebugMode())
	{
		::FreeConsole();
	}
}

// Create the App
void Program::CreateApp()
{
	SetApp(new App);
}

// Destory the App
void Program::DestoryApp()
{
	if (GetApp())
	{
		delete GetApp();

		SetApp(NULL);
	}
}

// Start the App
bool Program::StartApp()
{
	if (GetApp() == NULL)
	{
		return false;
	}

	if (!GetApp()->Start())
	{
		return false;
	}

	return true;
}

// Stop the the App
bool Program::StopApp()
{
	if (GetApp() == NULL)
	{
		return false;
	}

	if (!GetApp()->Stop())
	{
		return false;
	}

	if (IsDebugMode())
	{
		system("pause");
	}

	return true;
}

// Start the App
bool Program::Start()
{
	// Start the the App
	if (!StartApp())
	{
		return false;
	}

	return true;
}

// Stop the App
bool Program::Stop()
{
	// Stop the the App
	StopApp();

	return true;
}
